﻿using CWCS.Common;
using CWCS.Entity;
using CWCS.Entity.Convery;
using CWCS.Entity.SRM;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using Nti56.Modbus.Communication.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace CWCS.Core.Library.PLCManager
{
   public abstract class PLCHelper
   {
        // protected static Dictionary<string, OPCServer> PLCList = new Dictionary<string, OPCServer>();//PLC列表

       protected static Dictionary<string, SiemensS7Net> PLCList = new Dictionary<string, SiemensS7Net>();//PLC列表

       protected static Dictionary<string, ModbusConnectionInfo> ModbusList = new Dictionary<string, ModbusConnectionInfo>();//PLC列表

        protected TimerManager pft = new TimerManager();

       #region PLC事件
       /// <summary>
       /// 业务逻辑处理
       /// </summary>
       /// <param name="stationinfo"></param>
       public delegate void GetPLCTaskInfo(object entity);
       public event GetPLCTaskInfo GetTaskInfo;

       public delegate void SetPLChandshakeinfo(string handshake,string scno);
       public event SetPLChandshakeinfo handshakeinfo;

       /// <summary>
       /// 界面UI显示
       /// </summary>
       /// <param name="stationinfo"></param>
       public delegate void ShowEquipmentStatus(object equipinfo);
       public event ShowEquipmentStatus ShowStatus;

       /// <summary>
       /// 显示PLC交互时间
       /// </summary>
       /// <param name="Ip"></param>
       /// <param name="strDuration"></param>
       public delegate void ShowPLCConnectStatus(PLCStatus plcstatus);
       public event ShowPLCConnectStatus ShowPLCStatus;


       public delegate void ShowPLCMessage(string type, string msg);
       public event ShowPLCMessage ShowMessage;
       public PLCHelper plchelper;
       #endregion

      public abstract string[] ReadPLCInfo(string EquipNum,int index=0);

      #region event
      protected void ShowEquipmentPLCStatus(PLCStatus plcstatus)
       {
           if (ShowPLCStatus != null)
           {
               ShowPLCStatus(plcstatus);
           }
       }

      protected void ShowEquipmentTaskInfo(object entity)
       {
           if (GetTaskInfo != null)
           {
               GetTaskInfo(entity);
           }
       }
      protected void Sethandshakeinfo(string handshake,string scno)
      {
          if (handshakeinfo != null)
          {
              handshakeinfo(handshake,scno);
          }
      }

        protected void ShowUI(object equipinfo)
        {
            if (ShowStatus != null)
            {
                ShowStatus(equipinfo);
            }
        }

      protected void ShowMsg(string type, string msg)
      {
          if (ShowMessage != null)
          {
              ShowMessage.BeginInvoke(type,msg,null,null);
          }
      }
        ///// <summary>
        ///// PLC信息读取
        ///// </summary>
        ///// <param name="plc"></param>
        ///// <param name="DBAddress"></param>
        ///// <param name="Start"></param>
        ///// <param name="length"></param>
        ///// <param name="byt"></param>
        ///// <returns></returns>
        //public static bool ReadPlc(SiemensS7Net plc, int DBAddress, int Start, int length, ref byte[] byt)
        //{
        //    //地址：DB50.200  从200开始读取
        //    string DbAdd = string.Format("DB{0}.{1}", DBAddress, Start);

        //    OperateResult<byte[]> read = plc.Read(DbAdd, (ushort)length);  //同步读取           

        //    //判断读取是否成功
        //    if (read.IsSuccess)
        //    {
        //        byt = read.Content;
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}

        ///// <summary>
        ///// PLC信息写入
        ///// </summary>
        ///// <param name="plc"></param>
        ///// <param name="DBAddress"></param>
        ///// <param name="Start"></param>
        ///// <param name="length"></param>
        ///// <param name="byt"></param>
        ///// <returns></returns>
        //public static bool WritePlc(SiemensS7Net plc, int DBAddress, int Start, byte[] byt)
        //{
        //    string DbAdd = "";
        //    bool result = false;
        //    //写入变量赋值
        //    byte[] bytebuff = new byte[200];

        //    if (byt.Length > 200)
        //    {
        //        decimal d = (decimal)byt.Length / 200;

        //        decimal dcount = Math.Ceiling(d);

        //        int icount = (int)dcount;

        //        for (int i = 0; i < icount; i++)
        //        {
        //            DbAdd = string.Format("DB{0}.{1}", DBAddress, Start + i * 200);
        //            if (i == icount - 1)
        //            {
        //                int iednlen = byt.Length - 200 * i;

        //                bytebuff = new byte[iednlen];
        //                Array.Copy(byt, i * 200, bytebuff, 0, iednlen);
        //            }
        //            else
        //            {
        //                Array.Copy(byt, i * 200, bytebuff, 0, 200);
        //            }

        //            OperateResult write = plc.Write(DbAdd, bytebuff);
        //            result = write.IsSuccess;

        //            //写入失败，跳出
        //            if (!result)
        //            {
        //                break;
        //            }
        //        }
        //    }
        //    else
        //    {
        //        //200长度以内直接写入
        //        //地址：DB50.200  从200开始读取
        //        DbAdd = string.Format("DB{0}.{1}", DBAddress, Start);

        //        bytebuff = byt;

        //        OperateResult write = plc.Write(DbAdd, bytebuff);

        //        result = write.IsSuccess;
        //    }
        //    return result;
        //}
        #endregion
        public static bool ReadPlc(SiemensS7Net plc, int DBAddress, int Start, int length, ref byte[] byt)
        {
            //地址：DB50.200  从200开始读取
            string DbAdd = string.Format("DB{0}.{1}", DBAddress, Start);

            OperateResult<byte[]> read = plc.Read(DbAdd, (ushort)length);  //同步读取           

            //判断读取是否成功
            if (read.IsSuccess)
            {
                byt = read.Content;
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool SmartReadPlc(SiemensS7Net plc, int DBAddress, int Start, int length, ref byte[] byt)
        {
            //地址：DB50.200  从200开始读取
            string DbAdd = string.Format("DB{0}.{1}", DBAddress, Start);

            OperateResult<byte[]> read = plc.Read(DbAdd, (ushort)length);  //同步读取           

            //判断读取是否成功
            if (read.IsSuccess)
            {
                byt = read.Content;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// PLC信息写入
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="DBAddress"></param>
        /// <param name="Start"></param>
        /// <param name="length"></param>
        /// <param name="byt"></param>
        /// <returns></returns>
        public static bool WritePlc(SiemensS7Net plc, int DBAddress, int Start, byte[] byt)
        {
            string DbAdd = "";
            bool result = false;
            //写入变量赋值
            byte[] bytebuff = new byte[200];

            if (byt.Length > 200)
            {
                decimal d = (decimal)byt.Length / 200;

                decimal dcount = Math.Ceiling(d);

                int icount = (int)dcount;

                for (int i = 0; i < icount; i++)
                {
                    DbAdd = string.Format("DB{0}.{1}", DBAddress, Start + i * 200);
                    if (i == icount - 1)
                    {
                        int iednlen = byt.Length - 200 * i;

                        bytebuff = new byte[iednlen];
                        Array.Copy(byt, i * 200, bytebuff, 0, iednlen);
                    }
                    else
                    {
                        Array.Copy(byt, i * 200, bytebuff, 0, 200);
                    }

                    OperateResult write = plc.Write(DbAdd, bytebuff);
                    result = write.IsSuccess;

                    //写入失败，跳出
                    if (!result)
                    {
                        break;
                    }
                }
            }
            else
            {
                //200长度以内直接写入
                //地址：DB50.200  从200开始读取
                DbAdd = string.Format("DB{0}.{1}", DBAddress, Start);

                bytebuff = byt;

                OperateResult write = plc.Write(DbAdd, bytebuff);

                result = write.IsSuccess;

            }
            return result;
        }
    }
}
